<template>
  <span v-if="props.showText">{{ message }}</span>
  <el-select
    v-else
    v-model="dicSelect"
    class="select"
    :allow-create="props.allowCreate"
    :disabled="inputDisabled"
    :filterable="props.allowCreate || props.filterable"
    :placeholder="calcPlaceholder"
    @change="handleChange"
    @blur="handleBlur"
    clearable
    multiple
  >
    <el-option v-for="item in options"
      :key="item.key"
      :value="item.key"
      :label="item.value"
      :disabled="item.disabled === true"
    />
  </el-select>
</template>

<script setup>
import {ref, watch, onMounted, computed, onUnmounted} from 'vue';
import {useDictionaryStore} from '@/pinia/modules/dictionary';
import {useDisabled} from 'element-plus';
import {emitter} from "@/utils/bus";

const emit = defineEmits(['update:modelValue', 'change']);
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  dicCode: String,
  options: Array,
  allowCreate: {
    type: Boolean,
    default: false
  },
  filterable: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: '--请选择--'
  },
  showText: Boolean
})

const dictionaryStore = useDictionaryStore();
const options = ref([]);
const message = ref('');
const dicSelect = ref([]);
const inputDisabled = useDisabled();

const init = (data) => {
  dicSelect.value = [];
  message.value = '';
  options.value = [];

  dicSelect.value = data.modelValue ? data.modelValue.split(",") : [];
  if (data.options && data.options.length > 0) {
    if (data.options.length === 1) {
      let key = data.options[0].key;
      let value = data.options[0].value;
      if (key && value) {
        let keys = key.split(',');
        let values = value.split(',');
        keys.forEach((item, index) => {
          options.value.push({key: item, value: values[index]});
        });
      }
    } else {
      options.value = data.options;
    }
    calcValue();
  } else if (data.dicCode) {
    loadDicAndShow(data.dicCode);
    emitter.off('dictionary.change');
    emitter.on('dictionary.change', () => {
      loadDicAndShow(data.dicCode);
    });
  }
};

const handleChange = () => {
  let key = [], resultKey = [], resultValue = []; // 为了保证key与value同序
  if (dicSelect.value && options.value) {
    key = dicSelect.value;

    options.value.forEach(item => {
      if (key.indexOf(item.key) >= 0) {
        resultKey.push(item.key);
        resultValue.push(item.value);
      }
    });
  }

  emit('update:modelValue', resultKey.join(','), resultValue.join(','));
  emit('change', resultKey.join(','), resultValue.join(','));
};

const handleBlur = () => {
  handleChange();
};

const loadDicAndShow = async(dicCode) => {
  if ((dicCode || '') === '') {
    options.value = [];
  } else {
    options.value = await dictionaryStore.getDictionary(dicCode);
  }

  calcValue();
};

const calcValue = () => {
  if (options.value == null || options.value.length <= 0) {
    message.value = props.modelValue;
  } else {
    let optionValues = '';
    let values = (props.modelValue || '').split(',');
    values.forEach(value => {
      let option = options.value.find(item => item.key === value)
      if (option) {
        if (optionValues !== '') {
          optionValues += ',';
        }
        optionValues += option.value;
      }
    });
    message.value = optionValues;
  }
};

const calcPlaceholder = computed(() => {
  return inputDisabled.value === true ? '' : props.placeholder;
});

watch(() => props, (data) => {
  init(data);
}, {deep: true});

onMounted(() => {
  init(props);
});

onUnmounted(() => {
  emitter.off('dictionary.change');
});
</script>

<style scoped>
.select {
  width: 100%;
}
</style>